package demo.openvc.com.openvcdemo;

import android.Manifest;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.Toast;

import org.opencv.android.CameraBridgeViewBase;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import me.weyye.hipermission.HiPermission;
import me.weyye.hipermission.PermissionCallback;
import me.weyye.hipermission.PermissionItem;

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {

    private static final String TAG = MainActivity.class.toString();

    private CameraBridgeViewBase cameraBridgeViewBase;
    private Mat mGray;
    private Mat mRgba;
    private Mat gMatlin;
    private Mat Matlin;
    private int mAbsoluteFaceSize = 0;
    private ArrayList<PermissionItem> permissionItems = new ArrayList<>();

    static {
        System.loadLibrary("opencv_java4");
        Log.i(TAG, "OpenVC  JAVA Library Load Done");
    }


    private CascadeClassifier classifier;
    private Scalar faceRectColor = new Scalar(0, 255, 0, 255);
    private MatOfRect faces;
    private Rect[] faceArray;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initWindowSettings();
        permissionItems.add(new PermissionItem(Manifest.permission.CAMERA, "相机", R.drawable.permission_ic_camera));
        permissionItems.add(new PermissionItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, "文件存储", R.drawable.permission_ic_storage));

        setContentView(R.layout.activity_main);

        cameraBridgeViewBase = findViewById(R.id.camera_view);
        //设置前置摄像头

        cameraBridgeViewBase.setCvCameraViewListener(this);

        initClassifier();
        cameraBridgeViewBase.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_FRONT);
        cameraBridgeViewBase.enableView();


    }

    // 初始化人脸级联分类器，必须先初始化
    private void initClassifier() {
        try {
            InputStream is = getResources()
                    .openRawResource(R.raw.lbpcascade_frontalface);
            File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
            File cascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
            FileOutputStream os = new FileOutputStream(cascadeFile);
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            is.close();
            os.close();
            classifier = new CascadeClassifier(cascadeFile.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 初始化窗口设置, 包括全屏、横屏、常亮
    private void initWindowSettings() {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    @Override
    public void onCameraViewStarted(int width, int height) {
        mGray = new Mat();
        mRgba = new Mat();
        Matlin = new Mat();
        gMatlin = new Mat();


    }

    @Override
    public void onCameraViewStopped() {
        mGray.release();
        mRgba.release();


    }

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        mGray = inputFrame.gray();
        mRgba = inputFrame.rgba();

        //使前置的图像也是正的
        Core.flip(mRgba, mRgba, 1);
        Core.flip(mGray, mGray, 1);

        float mRelativeFaceSize = 0.6f;

        if (mAbsoluteFaceSize == 0) {
            int height = mGray.rows();
            if (Math.round(height * mRelativeFaceSize) > 0) {
                mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
            }
        }
        //修改角度
        Core.rotate(mGray, gMatlin, Core.ROTATE_90_CLOCKWISE);
        Core.rotate(mRgba, Matlin, Core.ROTATE_90_CLOCKWISE);

        faces = new MatOfRect();
        if (classifier != null) {
            classifier.detectMultiScale(gMatlin, faces, 1.1, 2, 2, new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
        }
        faceArray = faces.toArray();
        if (faceArray.length > 0) {
            takePhoto(mRgba);
        }

        return mRgba;

    }

    @Override
    protected void onResume() {
        super.onResume();

        HiPermission.create(MainActivity.this)
                .title("需要如下权限")
                .permissions(permissionItems)
                .checkMutiPermission(new PermissionCallback() {
                    @Override
                    public void onClose() {

                    }

                    @Override
                    public void onFinish() {

                    }

                    @Override
                    public void onDeny(String permission, int position) {

                    }

                    @Override
                    public void onGuarantee(String permission, int position) {

                    }
                });
    }

    private void takePhoto(final Mat rgba) {
        // Determine the path and metadata for the photo.
        //确定路径和照片元数据
        final long currentTimeMillis = System.currentTimeMillis();
        final String appName = getString(R.string.app_name);
        final String galleryPath =
                Environment.getExternalStoragePublicDirectory(
                        Environment.DIRECTORY_PICTURES).toString();
        final String albumPath = galleryPath + "/" + appName;
        final String photoPath = albumPath + "/" +
                currentTimeMillis + ".png";
        final ContentValues values = new ContentValues();
        values.put(MediaStore.MediaColumns.DATA, photoPath);
        values.put(MediaStore.Images.Media.MIME_TYPE,
                ShowImageActivity.PHOTO_MIME_TYPE);
        values.put(MediaStore.Images.Media.TITLE, appName);
        values.put(MediaStore.Images.Media.DESCRIPTION, appName);
        values.put(MediaStore.Images.Media.DATE_TAKEN, currentTimeMillis);
        // Ensure that the album directory exists.
        //确保相片目录存在
        File album = new File(albumPath);
        if (!album.isDirectory() && !album.mkdirs()) {
            Log.e(TAG, "Failed to create album directory at " +
                    albumPath);
            onTakePhotoFailed();
            return;
        }
        // Try to create the photo.
        //尝试创建照片

        Mat mBgr = new Mat();
        Imgproc.cvtColor(rgba, mBgr, Imgproc.COLOR_RGBA2BGR, 3);
        if (!Imgcodecs.imwrite(photoPath, mBgr)) {
            Log.e(TAG, "Failed to save photo to " + photoPath);//图片没有保存到
            onTakePhotoFailed();
        }
        Log.d(TAG, "Photo saved successfully to " + photoPath);//图片保存成功
        // Try to insert the photo into the MediaStore.
        //尝试插入图片到MediaStore
        Uri uri;
        try {
            uri = getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        } catch (final Exception e) {
            Log.e(TAG, "Failed to insert photo into MediaStore");//无法插入图像到MediaStore
            e.printStackTrace();
            // Since the insertion failed, delete the photo.
            //由于插入失败，删除图片
            File photo = new File(photoPath);
            if (!photo.delete()) {
                Log.e(TAG, "Failed to delete non-inserted photo");
            }
            onTakePhotoFailed();
            return;
        }
        // Open the photo in LabActivity.
        //打开照片在LabActivity
        final Intent intent = new Intent(this, ShowImageActivity.class);
        intent.putExtra(ShowImageActivity.EXTRA_PHOTO_URI, uri);
        intent.putExtra(ShowImageActivity.EXTRA_PHOTO_DATA_PATH,
                photoPath);
        startActivity(intent);
        finish();
    }

    private void onTakePhotoFailed() {

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (cameraBridgeViewBase != null) {
            cameraBridgeViewBase.disableView();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cameraBridgeViewBase.disableView();
    }


}
